package ext.demo;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import com.basicwtapi.authority.AuthFacade;
import com.basicwtapi.util.Select;
import com.ptc.netmarkets.workflow.NmWorkflowHelper;

import ext.tianma.number.util.DocUtil;
import wt.doc.WTDocument;
import wt.doc.WTDocumentMaster;
import wt.enterprise.Master;
import wt.enterprise.RevisionControlled;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceServerHelper;
import wt.fc.QueryResult;
import wt.inf.container.WTContainer;
import wt.inf.team.ContainerTeam;
import wt.inf.team.ContainerTeamHelper;
import wt.inf.team.ContainerTeamManaged;
import wt.method.RemoteMethodServer;
import wt.org.WTGroup;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.part.WTPartDescribeLink;
import wt.part.WTPartReferenceLink;
import wt.part.WTPartUsageLink;
import wt.project.Role;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionServerHelper;
import wt.team.Team;
import wt.type.ClientTypedUtility;
import wt.type.TypeDefinitionForeignKey;
import wt.type.TypeDefinitionReference;
import wt.type.Typed;
import wt.util.WTAttributeNameIfc;
import wt.util.WTException;
import wt.vc.VersionControlHelper;
import wt.vc.config.LatestConfigSpec;
import wt.workflow.WfException;
import wt.workflow.engine.WfActivity;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfVotingEventAudit;
import wt.workflow.work.WfAssignedActivity;
import wt.workflow.work.WorkItem;

public class Demo implements Serializable {
	private static final long serialVersionUID = 1L;

	public static void main(String[] args) {
		// 模拟登陆
		AuthFacade.searchService.loginNoPassword("wcadmin");

		// 根据number模糊查找物料WTPart
		List<WTPart> list = Select.from(WTPart.class).whereNumberLike(0, "000000018%").list();
		System.out.println("list : " + list);

		// 根据number精确查找物料
		WTPart first = Select.from(WTPart.class).whereNumberIs(0, "0000000181").first();
		System.out.println("list : " + first);
		WTPart first2 = Select.from(WTPart.class).where(0, WTPart.NUMBER, "=", "0000000181").first();
		System.out.println("list : " + first2);

		// 根据number模糊查找文档
		List<WTDocument> list2 = Select.from(WTDocument.class).whereNumberLike(0, "00000001%").list();
		System.out.println("list2: " + list2);

		// 根据number精确查找文档
		WTDocument doc = Select.from(WTDocument.class).whereNumberIs(0, "0000000141").first();
		System.out.println("doc:" + doc);

		// 多条件查询
		List<WTPart> list3 = Select.from(WTPart.class).whereNumberLike(0, "000000018%").whereNameLike(0, "%1").list();
		System.out.println("partlist: " + list3);

		// 多表联合查询， 根据文件number查找描述关系的Part
		List<WTPart> list4 = Select.from(WTPart.class).andFrom(WTDocument.class).andFrom(WTPartDescribeLink.class)
				.joinByLink(0, 2, 1).whereNumberIs(1, "0000000141").list();
		System.out.println("parts : " + list4);

		// 循环， 查找BOM结构
		Select<WTPart> sel = Select.from(WTPart.class).andFrom(WTPartUsageLink.class).andFrom(WTPart.class)
				.where(2, WTAttributeNameIfc.ID_NAME, "=", 1, WTAttributeNameIfc.ROLEA_OBJECT_ID)
				.where(0, Select.MASTER_ID_NAME, "=", 1, WTAttributeNameIfc.ROLEB_OBJECT_ID)
				.recursive(2, 0, "ida2a2", "ida2a2", 45797);
		System.out.println(sel);
		List<WTPart> bom = sel.list();
		for (WTPart cp : bom) {
			System.out.println("part: " + cp.getNumber() + " v:" + cp.getIterationIdentifier().getValue());
		}
		System.out.println(bom.size());
	}

	public static List<WTUser> getUser(WfProcess process, String name) throws WfException, WTException {
		try {

			List<WTUser> userList = new ArrayList<WTUser>();
			// QueryResult qr =
			// WorkflowCommands.getRouteStatus(oid);//分配了，没做的工作,有路由、计时器和工作任务等对象
			QueryResult qr = NmWorkflowHelper.service.getVotingEventsForProcess(process);// 分配了，做了的工作,有路由、计时器和工作任务等对象
			System.out.println("getWorkItemsFromWfProcess................size:" + qr.size());
			while (qr.hasMoreElements()) {
				WfVotingEventAudit wfvotingeventaudit = (WfVotingEventAudit) qr.nextElement();
				WorkItem workItem = wfvotingeventaudit.getWorkItem();// 获取工作任务
				if (null != workItem) {
					WfActivity wfa = (WfActivity) workItem.getSource().getObject();// 活动节点
					String activeName = wfa.getName();
					System.out.println("WorkItem................name:" + workItem.getDisplayIdentifier());
					System.out.println("WfActivity................Name:" + activeName);
					if (name.equals(activeName)) {
						// 如果是当前活动节点，则获取角色
						if (null != workItem.getRole()) {
							Role role = workItem.getRole();
							System.out.println("Role................Name:" + role.getDisplay());
							// 通过角色获取责任人
							Team team = (Team) process.getTeamId().getObject();
							WTPrincipalReference wtprincipalreference = null;
							Persistable persistable = null;
							WTUser wtuser = null;
							Enumeration enumPrin = team.getPrincipalTarget(role);
							while (enumPrin.hasMoreElements()) {
								wtprincipalreference = (WTPrincipalReference) enumPrin.nextElement();
								persistable = wtprincipalreference.getObject();
								if (persistable instanceof WTUser) {
									wtuser = (WTUser) persistable;
									userList.add(wtuser);
								}
							}

						}

					}

				}
			}
			System.out.println("userList..................size:" + userList.size());
			return userList;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static WfProcess getWfProcess(ObjectReference self) throws WTException {
		if (self == null) {
			return null;
		}
		Persistable persistable = self.getObject();
		if (persistable instanceof WfAssignedActivity) {
			return ((WfAssignedActivity) persistable).getParentProcess();
		} else if (persistable instanceof WfProcess) {
			return (WfProcess) persistable;
		}
		return null;
	}

	public void testRestGetMethod(ObjectReference self, String docType, String activeName) throws WTException {
		WfProcess process = (WfProcess) getWfProcess(self);
		List<WTUser> getUser = getUser(process, activeName);

	}

	/**
	 * 通过类型获取文档 Get WTDocument By Type and number
	 * 
	 * @author bjj
	 * @param type
	 * @param number
	 * @return
	 * @throws WTException
	 */
	@SuppressWarnings({ "deprecation" })
	public static List<WTDocument> getDocsByTypeAndNumberSuffix(String type, String number) throws WTException {
		try {
			List<WTDocument> result = new ArrayList<WTDocument>();
			if (!RemoteMethodServer.ServerFlag) {
				return (List<WTDocument>) RemoteMethodServer.getDefault().invoke("getDocsByTypeAndNumberSuffix",
						DocUtil.class.getName(), null, new Class[] { String.class, String.class },
						new Object[] { type, number });
			} else {
				boolean accessEnforced = SessionServerHelper.manager.setAccessEnforced(false);
				try {
					QuerySpec queryspec = new QuerySpec(WTDocument.class);
					TypeDefinitionReference clientType = ClientTypedUtility.getTypeDefinitionReference(type);
					SearchCondition searchCondition = new SearchCondition(WTDocument.class,
							Typed.TYPE_DEFINITION_REFERENCE + "." + TypeDefinitionReference.KEY + "."
									+ TypeDefinitionForeignKey.BRANCH_ID,
							SearchCondition.EQUAL, clientType.getKey().getBranchId());
					queryspec.appendWhere(searchCondition, new int[] { 0 });
					QueryResult queryresult = PersistenceServerHelper.manager.query(queryspec);
					queryresult = new LatestConfigSpec().process(queryresult);
					while (queryresult.hasMoreElements()) {
						Object object = queryresult.nextElement();
						if (object instanceof WTDocument) {
							WTDocument doc = (WTDocument) object;
							result.add(doc);
						}
					}
				} catch (Exception e) {
				} finally {
					SessionServerHelper.manager.setAccessEnforced(accessEnforced);
				}
				return result;
			}
		} catch (java.rmi.RemoteException e) {
		} catch (InvocationTargetException e) {
		}
		return null;
	}

	public static void removeReferenceDoc(WTPart part, WTDocument doc) throws WTException {
		try {
			if (!RemoteMethodServer.ServerFlag) {
				RemoteMethodServer.getDefault().invoke("removeReferenceDoc", Demo.class.getName(), null,
						new Class[] { WTPart.class, WTDocument.class }, new Object[] { part, doc });
			} else {
				boolean enforce = SessionServerHelper.manager.setAccessEnforced(false);
				// 通过部件获取说明文档
				QueryResult qr = PersistenceHelper.manager.navigate(part, WTPartReferenceLink.REFERENCES_ROLE,
						WTPartReferenceLink.class, false);
				try {
					while (qr.hasMoreElements()) {
						WTPartReferenceLink link = (WTPartReferenceLink) qr.nextElement();
						if (link != null) {
							WTPart p = link.getReferencedBy();
							WTDocumentMaster master = link.getReferences();
							WTDocument d = (WTDocument) getLatestRevision(master);
							if (part.getNumber().equals(p.getNumber()) && doc.getNumber().equals(d.getNumber())) {
								PersistenceServerHelper.manager.remove(link);
							}
						}
					}
					// 通过文档获取说明部件
					qr = PersistenceHelper.manager.navigate(doc, WTPartDescribeLink.DESCRIBES_ROLE,
							WTPartDescribeLink.class);
					while (qr.hasMoreElements()) {
						WTPartDescribeLink describeLink = (WTPartDescribeLink) qr.nextElement();
						describeLink.getDescribes();
					}

				} catch (Exception e) {

				} finally {
					SessionServerHelper.manager.setAccessEnforced(enforce);
				}
			}
		} catch (Exception e) {// java.rmi.RemoteException | InvocationTargetException e

		}
	}

	public static RevisionControlled getLatestRevision(Master master) {
		try {
			if (!RemoteMethodServer.ServerFlag) {
				return (RevisionControlled) RemoteMethodServer.getDefault().invoke("getLatestRevision",
						Demo.class.getName(), null, new Class[] { Master.class }, new Object[] { master });
			} else {
				boolean enforce = SessionServerHelper.manager.setAccessEnforced(false);
				RevisionControlled rc = null;
				if (master != null) {
					try {

						QueryResult qr = VersionControlHelper.service.allVersionsOf(master);
						while (qr.hasMoreElements()) {
							RevisionControlled obj = (RevisionControlled) qr.nextElement();
							if ((rc == null) || (obj.getVersionIdentifier().getSeries()
									.greaterThan(rc.getVersionIdentifier().getSeries()))) {
								rc = obj;
							}
						}
						if (rc != null)
							rc = (RevisionControlled) VersionControlHelper.getLatestIteration(rc, false);
					} catch (WTException e) {

					} finally {
						SessionServerHelper.manager.setAccessEnforced(enforce);
					}
				}
				return rc;
			}
		} catch (Exception e) {// java.rmi.RemoteException | InvocationTargetException e

		}
		return null;
	}

	public static List<WTUser> getUserFromRole(WTContainer wtContainer, String roleName) throws WTException {
		List<WTUser> users = new ArrayList<WTUser>();
		if (wtContainer == null || roleName == null) {
			return users;
		}
		ContainerTeam containerteam = ContainerTeamHelper.service.getContainerTeam((ContainerTeamManaged) wtContainer);
		containerteam.getAllMembers();
		containerteam.getMembers();
		Role role = Role.toRole(roleName);
		ArrayList<?> principalReferenceList = containerteam.getAllPrincipalsForTarget(role);

		for (Object obj : principalReferenceList) {
			WTPrincipalReference wtPrincipalReference = (WTPrincipalReference) obj;
			WTPrincipal principal = (WTPrincipal) wtPrincipalReference.getObject();
			if (principal instanceof WTUser) {
				WTUser user = (WTUser) principal;
				users.add(user);
			} else if (principal instanceof WTGroup) {
				WTGroup group = (WTGroup) principal;
				List<WTUser> list = null;
				// getUserFromGroup(group);
				users.addAll(list);
			}
		}
		return users;
	}

}
